import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:honeypotflutter/public/views/public_empty.dart';
import 'package:pull_to_refresh/pull_to_refresh.dart';
import 'package:get/get.dart';

import '../public_uuid.dart';

class HLRefresh<T> extends StatefulWidget {
  /// 刷新
  final bool isRefresh;

  /// 加载
  final bool isLoading;

  /// 分页每页数据条数【默认10】
  final int pageCount;

  /// 刷新请求
  final Future<List<T>> Function()? onRefresh;

  /// 加载请求
  final Future<List<T>> Function()? onLoading;

  /// 刷新
  final HLRefreshController? refreshController;

  /// 数据
  final HLRefreshDataController? dataController;

  /// item
  final Widget Function(T data, int index) snap;

  /// 显示分割线
  final bool showSeparated;

  /// padding
  final EdgeInsetsGeometry? padding;

  /// tag
  final String? tag;

  HLRefresh({
    super.key,
    this.isRefresh = true,
    this.isLoading = true,
    this.refreshController,
    this.onLoading,
    this.onRefresh,
    this.pageCount = 10,
    this.showSeparated = true,
    this.padding,
    this.tag,
    this.dataController,
    required this.snap,
  });

  @override
  State<HLRefresh> createState() => _HLRefreshState<T>();
}

class _HLRefreshState<T> extends State<HLRefresh<T>> {
  /// 刷新
  late HLRefreshController _refreshController;
  late HLRefreshDataController _controller;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    String? newTag = widget.tag;
    if (widget.dataController == null && widget.tag == null) {
      newTag = HLUUid.v4();
    }
    _controller = widget.dataController ?? Get.put(HLRefreshDataController<T>(), tag: newTag);
    _refreshController = widget.refreshController ?? HLRefreshController(initialRefresh: true);
    _refreshController.initFinsh = true;
  }

  @override
  Widget build(BuildContext context) {
    return Obx(() {
      return SmartRefresher(
        controller: _refreshController,
        enablePullDown: widget.isRefresh,
        enablePullUp: widget.isLoading,
        header: CustomHeader(builder: (BuildContext context, RefreshStatus? mode) {
          Widget body;
          if (mode == RefreshStatus.idle) {
            body = const Text("下拉刷新...");
          } else if (mode == RefreshStatus.completed) {
            body = const Text("数据加载完成");
          } else {
            body = const Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                CupertinoActivityIndicator(),
                Padding(
                  padding: EdgeInsets.only(left: 10),
                  child: Text("数据加载中..."),
                ),
              ],
            );
          }
          return SizedBox(
            height: 55.0,
            child: Center(child: body),
          );
        }),
        footer: CustomFooter(
          builder: (BuildContext context, LoadStatus? mode) {
            Widget body;
            if (mode == LoadStatus.idle) {
              body = const Text("上拉加载更多");
            } else if (mode == LoadStatus.loading) {
              body = const Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  CupertinoActivityIndicator(),
                  Padding(
                    padding: EdgeInsets.only(left: 10),
                    child: Text("数据加载中..."),
                  ),
                ],
              );
            } else if (mode == LoadStatus.failed) {
              body = const Text("加载失败！点击重试！");
            } else if (mode == LoadStatus.canLoading) {
              body = const Text("上拉加载更多...");
            } else {
              body = Container();
            }
            return SizedBox(
              height: 55,
              child: Center(child: body),
            );
          },
        ),
        onRefresh: requestRefresh,
        onLoading: requestLoading,
        child: (_controller.data.length > 0)
            ? ListView.separated(
                padding: widget.padding,
                itemBuilder: (BuildContext context, int index) {
                  return widget.snap(_controller.data[index], index);
                },
                separatorBuilder: (BuildContext context, int index) {
                  return widget.showSeparated
                      ? Divider(
                          color: Color.fromRGBO(238, 238, 238, 1),
                          indent: 16,
                          endIndent: 16,
                          thickness: 0,
                          height: 1,
                        )
                      : Container();
                },
                itemCount: _controller.data.length,
              )
            : Scrollbar(child: HLEmpty()),
      );
    });
  }

  ///刷新
  void requestRefresh() async {
    if (widget.onRefresh == null) {
      return;
    }
    List<T> tempData = [];
    widget.onRefresh!().then((value) {
      _controller.data.clear();
      tempData = value;
      _controller.data.addAll(value);
    }).whenComplete(() {
      _refreshController.refreshCompleted();
      if (tempData.length < widget.pageCount) {
        _refreshController.loadNoData();
      } else {
        _refreshController.resetNoData();
      }
    });
  }

  ///加载
  void requestLoading() async {
    if (widget.onLoading == null) {
      return;
    }
    List<T> tempData = [];
    widget.onLoading!().then((value) {
      tempData = value;
      _controller.data.addAll(tempData);
    }).whenComplete(() {
      if (tempData.length < widget.pageCount) {
        _refreshController.loadNoData();
      } else {
        _refreshController.loadComplete();
      }
    });
  }

  @override
  void dispose() {
    Get.delete<HLRefreshDataController>(tag: widget.tag);
    super.dispose();
  }
}

/*
* 数据
* */
class HLRefreshDataController<T> extends GetxController {
  final data = RxList<T>();
}

/*
* 刷新封装
* */
class HLRefreshController extends RefreshController {
  bool initFinsh = false;
  HLRefreshController({super.initialRefresh, super.initialLoadStatus, super.initialRefreshStatus});

  @override
  Future<void>? requestRefresh({bool needMove = true, bool needCallback = true, Duration duration = const Duration(milliseconds: 500), Curve curve = Curves.linear}) {
    // TODO: implement requestRefresh
    if (!initFinsh) {
      return null;
    }
    return super.requestRefresh(
      needMove: needMove,
      needCallback: needCallback,
      duration: duration,
      curve: curve,
    );
  }

  @override
  Future<void>? requestLoading({bool needMove = true, bool needCallback = true, Duration duration = const Duration(milliseconds: 300), Curve curve = Curves.linear}) {
    // TODO: implement requestLoading
    if (!initFinsh) {
      return null;
    }
    return super.requestLoading(
      needMove: needMove,
      needCallback: needCallback,
      duration: duration,
      curve: curve,
    );
  }
}
